package com.day10;

/**
 * 面向对象特征之三:
 * 多态性
 * 1.理解多态性: 可以理解为一个事物的多种形态。
 * 2.何为多态性:
 * 对象的多态性: 父类的引用指向子类的对象。(或者子类的对象赋给父类的引用)
 * 3.多态的使用,虚拟方法调用
 * 有了对象多态性以后，我们在编译期，只能调用父类中声明的方法，但在运行期，我们实际执行的是子类重写的父类方法。
 * 总结: 编译，看左边，运行，看右边。
 * 4.多态性的前提: （1）类的继承关系，(2)要有方法的重写，不然毫无意义
 * <p>
 * 5.对象的多态性:只适用于方法，不适用于属性。(编译和运行都看左边)
 * <p>
 * <p>
 * *********************************************
 */
public class PersonTest {

    public static void main(String[] args) {
        Person person = new Person();

        person.eat();

        Man man = new Man();
        man.eat();
        man.age = 25;
        man.earnMoney();


        //多态性*************************
        //对象的多态性:父类的引用指向子类的对象。
        Person person2 = new Man();
        //多态的使用: 当调用子父类同名同参数的方法时，实际执行的是子类重写父类的方法。----虚拟方法调用。
        person2.eat();

        //编译时看父类引用，运行时是子类实例。
        //有了对象的多态性后，内存中实际加载了子类特有的属性和方法，但是由于变量声明为父类类型，导致编译时，只能调用父类中声明的属性和方法，子类特有的属性和方法不能调用。
        //如何才能调用子类特有的属性和方法，使用强制类型转换符号，向下转型。
        //子类转换为父类，只需多态就可以，父类转换为子类需要进行instanceof判断，然后进行强制类型转换。

        /**
         * a instanceof A: 判断对象a是否是类A的实例，如果是，返回true,如果不是，返回false.
         *
         *
         * 使用情景:为了避免向下转型时出现ClassCastException的异常，我们在向下转型前，先进行instanceof的判断，一旦返回true,就进行向下转型，如果返回false,不进行向下转型。
         *
         *
         * 如果a instanceof A 返回true,则 a instanceof B 返回true
         */
        if (person2 instanceof Woman) {
            Woman woman = (Woman)person2;
            woman.goShopping();
            System.out.printf("??????????????");
        }

    }
}
